﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using SuperMoney.Datas.DbModels;

namespace SuperMoney.Datas
{
	public class DeviceAccountDbService
	{
		public static readonly DeviceAccountDbService Instance = new DeviceAccountDbService();

		public MRMEntities NewDB()
		{
			return new MRMEntities();
		}

		public DeviceAccount Create(string deviceId, int integral, string device)
		{
			using (var db = MRMDB.New())
			{
				DeviceAccount deviceAccount = new DeviceAccount();
				deviceAccount.DeviceId = deviceId;
				deviceAccount.IntegralBalance = integral;
				deviceAccount.Device = device;
				deviceAccount.AddTime = DateTime.Now;
				deviceAccount.UpdateTime = DateTime.Now;

				db.DeviceAccountSet.Add(deviceAccount);
				db.SaveChanges();
				return deviceAccount;
			}
		}

		public DeviceAccount Get(string deviceId)
		{
			using (var db = this.NewDB())
			{
				return db.DeviceAccountSet.Where(p => p.DeviceId == deviceId).SingleOrDefault();
			}
		}

		internal DeviceAccount Get(string deviceId, MRMEntities db)
		{
			return db.DeviceAccountSet.Where(p => p.DeviceId == deviceId).SingleOrDefault();
		}

		internal DeviceAccount GetOrCreate(string deviceId, MRMEntities db)
		{
			var deviceAccount = this.Get(deviceId, db);

			if (deviceAccount == null)
			{
				deviceAccount = new DeviceAccount();
				deviceAccount.DeviceId = deviceId;
				deviceAccount.IntegralBalance = 0;
				deviceAccount.AddTime = DateTime.Now;
				deviceAccount.UpdateTime = DateTime.Now;

				db.DeviceAccountSet.Add(deviceAccount);
				db.SaveChanges();
			}

			return deviceAccount;
		}

		public bool Exists(string deviceId)
		{
			using (var db = MRMDB.New())
			{
				return db.DeviceAccountSet.Where(m => m.DeviceId == deviceId).Count() > 0;
			}
		}

		public int AddIntegralBalance(string deviceId, int integral)
		{
			if (integral <= 0)
			{
				throw new Exception("增加积分值({0})错误");
			}
			return this.ChangeIntegralBalance(deviceId, integral);
		}

		public int SubIntegralBalance(string deviceId, int integral)
		{
			if (integral <= 0)
			{
				throw new Exception("减少积分值({0})错误");
			}
			return this.ChangeIntegralBalance(deviceId, -integral);
		}

		private int ChangeIntegralBalance(string deviceId, int integral)
		{
			int integralBalance;
			using (var db = this.NewDB())
			{
				using (var tx = new TransactionScope())
				{
					var deviceAccount = this.GetOrCreate(deviceId, db);
					deviceAccount.IntegralBalance += integral;
					deviceAccount.UpdateTime = DateTime.Now;
					db.SaveChanges();
					integralBalance = deviceAccount.IntegralBalance;

					tx.Complete();
				}
			}
			return integralBalance;
		}
	}
}
